package com.zhou.util;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.zhou.core.xml.XmlReader;
import net.sf.json.xml.XMLSerializer;
import org.dom4j.*;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
import org.xml.sax.SAXException;

import java.io.*;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;


public class XmlDom4jUtils
{
  public static final String BR = System.getProperty("line.separator");

  public static Document load(String classPathFileName)
    throws Exception
  {
    SAXReader sr = new SAXReader(); // 需要导入jar包:dom4j
    // 关联xml
    Document document = sr.read(XmlDom4jUtils.class.getClassLoader().getResourceAsStream(classPathFileName));
    return document;
  }

  public static Document load(File file)
    throws Exception
  {
    SAXReader sr = new SAXReader(); // 需要导入jar包:dom4j
    Document document = sr.read(file);
    return document;
  }



  public static boolean checkValidity(String paramString)
  {
    String[] arrayOfString = paramString.split(".");
    return arrayOfString[(arrayOfString.length - 1)].equals("xml");
  }

  public static boolean isXml(String paramString)
  {
    return paramString.toLowerCase().endsWith("xml");
  }





  public static String getChildText(Element paramElement, String paramString)
  {
    Element localElement = getChildByName(paramElement, paramString);
    if (localElement == null)
      return "";
    return getText(localElement);
  }


public static Element[] getChildrenByName(Element parentElement, String eleName)
  {
    Collection<Element> els =  XmlReader.readElements(parentElement,eleName);
    if (els == null) return new Element[0];
    return els.toArray(new Element[els.size()]);
  }

  public static Element getChildByName(Element parentElement, String eleName)
  {
    Element[] arrayOfElement = getChildrenByName(parentElement, eleName);
    if (arrayOfElement.length == 0)
      return null;
    if (arrayOfElement.length > 1)
      throw new IllegalStateException("Too many (" + arrayOfElement.length + ") '" + eleName + "' elements found!");
    return arrayOfElement[0];
  }

  public static String getText(Element ele)
  {
    return ele.getText();
  }

  public static String getAttribute(Element ele, String attributeName)
  {
    return ele.attributeValue(attributeName);
  }

  public static int getIntValue(Element paramElement)
  {
    return Integer.valueOf(getText(paramElement)).intValue();
  }

  public static Long getLongValue(Element paramElement)
  {
    return Long.valueOf(getText(paramElement));
  }

  public static byte getByteValue(Element paramElement)
  {
    return Byte.valueOf(getText(paramElement)).byteValue();
  }


  public static void save(Document document,String toFileName )
    throws Exception
  {
    Writer osWrite = null;
    XMLWriter writer = null;// XMLWriter
    try {
      osWrite = new OutputStreamWriter(new FileOutputStream(toFileName),"UTF-8");// 创建输出流
      OutputFormat format = OutputFormat.createPrettyPrint(); // 获取输出的指定格式
      format.setEncoding("UTF-8");// 设置编码 ，确保解析的xml为UTF-8格式
      writer = new XMLWriter(osWrite, format);
      // 指定输出文件以及格式
      writer.write(document);// 把document写入xmlFile指定的文件(可以为被解析的文件或者新创建的文件)
      writer.flush();
    } catch (Exception e) {
      throw e;
    } finally {
      if (osWrite != null) writer.close();
    }

  }


  public static Element createChild(Element parentElement, String eleName)
  {
    return parentElement.addElement(eleName);
  }




  /**
   * xml转成 JSON对象
   * org.dom4j.Document 转  com.alibaba.fastjson.JSONObject
   * @param xml
   * @return

   */
  public static JSONObject xml2JSON(String xml) throws Exception {
    JSONObject result = new JSONObject();
    Element rootElement = load(xml).getRootElement();
     result.put(rootElement.getName(),elementToJSONObject(rootElement));
    return result;
  }

  /**
   * xml转成 JSON对象
   * @param file
   * @return
   * @throws Exception
   */
  public static JSONObject xml2JSON(File file) throws Exception {
    JSONObject result = new JSONObject();
    Element rootElement = load(file).getRootElement();
    result.put(rootElement.getName(),elementToJSONObject(rootElement));
    return result;
  }

  /**
   * org.dom4j.Element 转  com.alibaba.fastjson.JSONObject
   * @param node
   * @return
   */
  public static JSONObject elementToJSONObject(Element node) {
    JSONObject result = new JSONObject();
    // 当前节点的名称、文本内容和属性
    List<Attribute> listAttr = node.attributes();// 当前节点的所有属性的list
    for (Attribute attr : listAttr) {// 遍历当前节点的所有属性
      result.put(attr.getName(), attr.getValue());
    }
    // 递归遍历当前节点所有的子节点
    List<Element> listElement = node.elements();// 所有一级子节点的list
    if (!listElement.isEmpty()) {
      for (Element e : listElement) {// 遍历所有一级子节点
        if (e.attributes().isEmpty() && e.elements().isEmpty()) // 判断一级节点是否有属性和子节点
          result.put(e.getName(), e.getTextTrim());// 沒有则将当前节点作为上级节点的属性对待
        else {
          if (!result.containsKey(e.getName())) // 判断父节点是否存在该一级节点名称的属性
          {
            result.put(e.getName(), new JSONArray());// 没有则创建
          }
          ((JSONArray) result.get(e.getName())).add(elementToJSONObject(e));// 将该一级节点放入该节点名称的属性对应的值中
        }
      }
    }
    return result;
  }



}
